package commons.params_appli;

import commons.logs.Logger;


public class ParamsAppli extends A_ParamsAppli {

	// impossibilité totale de lancer une partie du logiciel ?
	static public boolean canLaunchLigneSite = true;
	static public boolean canLaunchAnno = true;
	
	// limitations sur les anno ?
	static public boolean hasLimitationForAnno = true;
	static public String dateMaxForAnno = "2015-12-31 23:59:59";
	
	// limitations sur les lignes/sites ?
	static public boolean hasLimitationForLS = false;
	
	static public int maxNbNodes = 10_000_000;


	@Override
	protected void registerAll() {

		//**********************************************************************
		//****  Paramètres communs entre la Passerelle et AutoGene *************
		//**********************************************************************
		register("Common.REPERTOIRE_DONNEES", ParamCondition_Directory_Existant);
		register("Common.SOUS_REP_FICHIERS_SOURCE", ParamCondition_SubDirectory);
		register("Common.SOUS_REP_FICHIERS_TRAITES", ParamCondition_SubDirectory);
		register("Common.SOUS_REP_MDB_RESULT", ParamCondition_SubDirectory);

		register("Common.EXTENSION_FICHIER_ECHANGE", ParamCondition_FileExtension);
		register("Common.CHARSET_FICHIER_ECHANGE", ParamCondition_FileText_Charset);



		//**********************************************************************
		//**** Paramètres d'AutoGene (communs à LigneSite et Anno) *************
		//**********************************************************************

		//******** DIVERS ******************************************************
		// Niveau de log
		String[] listNiveauLog = new String[] {"DEBUG2", "DEBUG1", "INFO2", "INFO1", "WARN_", "ERROR"};
		register("Autogene.NIVEAU_LOG", new ParamCondition(listNiveauLog, true), "INFO1");

		//******** REPERTOIRES ET FICHIERS *************************************
		// Paramétrages de traitement
		register("Autogene.REPERTOIRE_PARAM_TRAITEMENT_LS", ParamCondition_Directory_Existant);
		register("Autogene.REPERTOIRE_PARAM_TRAITEMENT_ANNO", ParamCondition_Directory_Existant);



		//***** AFFICHAGE ******************************************************
		// Taille pixel en mètre
		register("Autogene.TAILLE_PIXEL", ParamCondition_Float_StrictPos);

		// Couleur des objects sélectionnés et en surbrillance
		register("Autogene.COULEUR_SELECTION", ParamCondition_Color);
		register("Autogene.COULEUR_SURBRILLANCE", ParamCondition_Color);

		// Couleur et dimension par defaut des points et segments
		// Des couleurs particulières doivent être définies lors du paramétrage du traitement
		register("Autogene.EPAISSEUR_SEGMENT", ParamCondition_Float_StrictPos);
		register("Autogene.RAYON_POINT", ParamCondition_Float_StrictPos);
		
		register("Autogene.COULEUR_SEGMENT", ParamCondition_Color);
		register("Autogene.COULEUR_BORD_POINT", ParamCondition_Color);
		register("Autogene.COULEUR_INTERIEUR_POINT", ParamCondition_Color);

		// Taille (en mètre) rectangle de visualisation si zoom sur un objet ponctuel
		register("Autogene.LARGEUR_ZOOM_OBJECT_POINT", ParamCondition_Float_StrictPos);


		//***** PERFORMANCES ***************************************************
		// Optimisation des dessins des objets type ligne
		// (en fait, que les path de l'algo LignesSites)
		register("Autogene.TOLERANCE_SIMPLIFICATION_LINE_PX", ParamCondition_Float_Pos);

		// Nombre de CPU de l'ordinateur
		register("Autogene.NB_CPU", ParamCondition_Integer_Pos);

		// Taille index spatiaux
		register("Autogene.INDEX_SPATIAL_NB_CASE_PAR_OBJET", ParamCondition_Integer_StrictPos);
		register("Autogene.INDEX_SPATIAL_NB_CASE_MAX", ParamCondition_Integer_StrictPos);

		// nb max de junctions affichée en meme temps (surtout pour le mode TOPO)
		register("Autogene.LS_NBMAX_JUNCTION_ON_MAP", ParamCondition_Integer_StrictPos);


		//***** IO *************************************************************
		register("Autogene.PRECISION_X_Y_POUR_IO", new ParamCondition(Condition.INTEGER_BETWEEN, 0, 12, false));

		// Export ou non de couches spéciales d'information
		register("Autogene.EXPORT_COUCHE_ZONE", ParamCondition_Bool);
		register("Autogene.EXPORT_COUCHE_ANNO_RECT_ENGLOB", ParamCondition_Bool);
		register("Autogene.EXPORT_COUCHE_LIEN_ANNO_SITE", ParamCondition_Bool);



		//**********************************************************************
		//**** Paramètres d'AutoGene , algo LIGNES-SITES ***********************
		//**********************************************************************
		
		// Le calcul de complexité (servant à limiter les déplacements des points dans les zones denses)
		//  recherche les points multiples alentours, et suivant leur distance et leur taille accroissent
		//  ou non la complexité à l'endroit recherché)
		// Cette distance de recherche est un facteur de la taille du point testé
		register("LigneSite.FACTEUR_RECHERCHE_POUR_CALCUL_COMPLEXITE", ParamCondition_Float_StrictPos);
		// Facteur de décroissance de l'influence des points multiples en fonction de leur distance au point testé
		register("LigneSite.FACTEUR_DECROISSANCE_INFLUENCE_POUR_CALCUL_COMPLEXITE", ParamCondition_Float_StrictPos);

		// Si 2 node sont trop proches, on doit prendre un rayon de simplification plus petit que la distance entre les nodes
		//  en fait on prend un facteur de cette distance et c'est ce paramètre qui est utilisé
		register("LigneSite.FACTEUR_REDUCTION_ZONE_SIMPLIFICATION_NODE", new ParamCondition(Condition.FLOAT_BETWEEN_STRICT, 0, 1, false));


		register("LigneSite.FACTEUR_LG_MAX_ENTRE_2_BARBULES", ParamCondition_Float_StrictPos);

		// Simplification topo : activation ou non de certains patterns
		register("LigneSite.SIMPLIF_TOPO_3_1", ParamCondition_Bool);
		register("LigneSite.SIMPLIF_TOPO_2_1", ParamCondition_Bool);
		register("LigneSite.SIMPLIF_TOPO_BOUCLE_NODE", ParamCondition_Bool);
		register("LigneSite.SIMPLIF_TOPO_PETIT_PATH", ParamCondition_Bool);
		
		// Algo de répulsion
		register("LigneSite.USE_ANGLE_BETWEEN_SEG", ParamCondition_Bool);
		register("LigneSite.MIN_COS", new ParamCondition(Condition.FLOAT_BETWEEN, 0, 1, false));

		//----------------------------------------------------------------------
		// divers
		
		// Durant le traitement, on arrête tout si des junction sortent du rectangle contenant l'ensemble des données
		//  dont la taille est multipliée par ce paramètres, qui autorise donc aux données à sortir de ce rectangle
		//  jusqu'à une limite donnée
		register("LigneSite.FACTEUR_DETECTION_DIVERGENCE", new ParamCondition(Condition.FLOAT_BETWEEN_STRICT, 1, 100, false));

		// A desactiver si bug
		// Snap des junctions sur le bord des zones si le segment en question a été coupé par la zone
		//  -> assure une restitution correcte, sans "trou" pres des bords des zones
		register("LigneSite.SNAP_JONCTION_TO_ZONE", ParamCondition_Bool);

		// Max de node auquel est connecte directement ou non un Path
		register("LigneSite.NB_MAX_NODE_CONNECTED_TO_PATH", ParamCondition_Integer_StrictPos);


		//**********************************************************************
		//**** Paramètres d'AutoGene , algo ANNO *******************************
		//**********************************************************************

		// Découpage des données en 1ère passe
		register("Anno.UTILISE_DECOUPAGE_DONNEE_PASSE_1", ParamCondition_Bool);
		// nb de combinaisons pour le calcul de préplacement
		register("Anno.PREPLACEMENTANNO_NBX", ParamCondition_Integer_StrictPos);
		register("Anno.PREPLACEMENTANNO_NBY", ParamCondition_Integer_StrictPos);
		// réduction de ce nombre de combinaisons dans le cas du pré-placement approximatif
		register("Anno.PREPLACEMENTANNO_FACTEURREDUCTION_PREPLACEMENT_APPROX", ParamCondition_Integer_StrictPos);
		// note seuil en deca de laquelle une annotation pré-placée approximativement est acceptée
		//  trop grand -> sous-découpage fonctionne mieux mais moins optimisé au global
		//  car le groupe des anno pré-placée approx devient très grand, or il s'agit d'anno
		//  qui peuvent avoir des intéractions avec les autres (notamment en frontière de groupe des anno approx)
		//  au niveau de leur emplacement optimal
		register("Anno.SEUIL_NOTE_PREPLACEMENT_APPROX", new ParamCondition(Condition.FLOAT_BETWEEN, 0, 1, false));

		register("Anno.DIST_HYBRIDE_PONDERATION_COIN", new ParamCondition(Condition.FLOAT_BETWEEN, 0, 1, false));
	}


	@Override
	protected void postTraitement() {
		// Niveau de log
		Logger.log_INFO1("Niveau de log : " + getParam("Autogene.NIVEAU_LOG")); // on est sur que ce msg va s'afficher car initialement, le niveau est DEBUG2
		Logger.setOutLevel(Logger.Level.valueOf(getParam("Autogene.NIVEAU_LOG")));
		// comme on connait le niveau de log, on affiche les logs de lecture du fichier INI qui ont été mémorisés
		logLectureFichierINI();

		// Si nombre de CPU déclaré à 0, cela signifie que l'utilisateur laisse
		//  AutoGene déterminer leur nombre automatiquement
		String msgInfo = "";
		int nbCPU = getParam_i("Autogene.NB_CPU");
		if (nbCPU == 0) {
			msgInfo = "Pas de nb de CPU déclaré dans les paramètres => détection automatique\n";
			nbCPU = Runtime.getRuntime().availableProcessors();
			assert (nbCPU>0) : "Erreur dans le nombre de CPU détectés : " + nbCPU + " -> forcer le nb de CPU dans les paramètres";
			setParam("Autogene.NB_CPU", nbCPU);
			msgInfo += " -> nb CPU détectés = " + nbCPU;
		} else {
			msgInfo = "Nb CPU utilisés pour les traitements : " + nbCPU;
		}
		Logger.log_INFO1(msgInfo);

		
		// Variables pré lue car accès très fréquent et getParam() fait appel à un HashSet,
		//  donc pas forcément optimisé pour un accès fréquent
		B_USE_COS = getParam_b("LigneSite.USE_ANGLE_BETWEEN_SEG");
		MIN_COS = getParam_d("LigneSite.MIN_COS");
		
		ANNO_DISTHYBRIDE_FACT_COIN = getParam_d("Anno.DIST_HYBRIDE_PONDERATION_COIN");
		ANNO_DISTHYBRIDE_FACT_BORD = 1 - ANNO_DISTHYBRIDE_FACT_COIN;
	}

	// Variables pré lue car accès très fréquent et getParam() fait appel à un HashSet,
	//  donc pas forcément optimisé pour un accès fréquent
	// -- Ligne Site --
	public static boolean B_USE_COS = false;
	public static double MIN_COS = 1;
	// -- Anno --
	public static double ANNO_DISTHYBRIDE_FACT_BORD = Double.NaN;
	public static double ANNO_DISTHYBRIDE_FACT_COIN = Double.NaN;
	


	// Vérifications complémentaires à celles par défaut faites individuellement
	@Override
	protected void checkValidity() {

	}
	

	
	//**************************************************************************
	// ANNOTATIONS
	//**************************************************************************


	public static int ANNO_NB_MIN_SITE_IN_SOUSGROUPE = 8; // il pourra y en avoir le double apres regroupement !

	public static double ANNO_MUTATION_FACTOR_ADJUST = 0.5; // 0.5 mieux que *0.3 (0.6, 0.45, 0.4 moins bien) TODO PARAM


}
